package org.datascooter.cglib.proxy.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.datascooter.cglib.proxy.ObjectWrapper;
import org.datascooter.cglib.proxy.SimpleInterceptor;
import org.datascooter.exception.EntityNotMappedException;
import org.datascooter.inface.IDataManager;

public class ProxySet<T> extends SimpleInterceptor implements Set<T> {

	private static final long serialVersionUID = -3639014671567440108L;
	private Set<T> set;

	public ProxySet(SimpleInterceptor parent, Object container, String containerAttribute, IDataManager dataManager) {
		super(parent, container, containerAttribute, dataManager);
	}

	@Override
	public Object getSource() {
		return set;
	}

	@Override
	protected void saveContent(String attributeName, Object[] args) throws EntityNotMappedException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {
		super.saveContent(attributeName, args);
		set.add((T) args[0]);
	}

	@Override
	public void setContainer(Object object) {
		container = object;
		set = new HashSet<T>();
		List<T> containerList = crossProvider.getContent(container, containerAttribute);
		for (T item : containerList) {
			try {
				ObjectWrapper.wrap(manager, item);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
			set.add(item);
		}
	}

	public int size() {
		return set.size();
	}

	public boolean isEmpty() {
		return set.isEmpty();
	}

	public boolean contains(Object o) {
		return set.contains(o);
	}

	public Iterator<T> iterator() {
		return set.iterator();
	}

	public Object[] toArray() {
		return set.toArray();
	}

	@SuppressWarnings("hiding")
	public <T> T[] toArray(T[] a) {
		return set.toArray(a);
	}

	public boolean add(T e) {
		return set.add(e);
	}

	public boolean remove(Object o) {
		return set.remove(o);
	}

	public boolean containsAll(Collection<?> c) {
		return set.containsAll(c);
	}

	public boolean addAll(Collection<? extends T> c) {
		return set.addAll(c);
	}

	public boolean retainAll(Collection<?> c) {
		return set.retainAll(c);
	}

	public boolean removeAll(Collection<?> c) {
		return set.removeAll(c);
	}

	public void clear() {
		set.clear();
	}

	public boolean equals(Object o) {
		return set.equals(o);
	}

	public int hashCode() {
		return set.hashCode();
	}
}
